# TODO: Add comment
# 
# Author: Roger
###############################################################################

setClass("Swaption",
		representation=list(),
		contains=c("OptionType","Strike","Nominal","ImpliedVolatility","FixPaymentFrequency","SituationDate","EffectiveDate","MaturityDate","BasicInstrument","DayCountConvention","Exchange")
)

Swaption <- function(OptionType,Strike,Nominal,ImpliedVolatility,FixPaymentFrequency,SituationDate,EffectiveDate,MaturityDate,Currency,Name,DayCountConvention,Exchange){
	new("Swaption",OptionType=OptionType,Strike=Strike,Nominal=Nominal,ImpliedVolatility=ImpliedVolatility,FixPaymentFrequency=FixPaymentFrequency,SituationDate=SituationDate,EffectiveDate=EffectiveDate,MaturityDate=MaturityDate,Currency=Currency,Name=Name,DayCountConvention=DayCountConvention,Exchange=Exchange)
}

# SituationDate <- DateYMD(2010,10,21)
# x <- object <- Swaption("Payer",5,1000000,35,1,SituationDate,plusYear(SituationDate,20),plusYear(SituationDate,30),"CHF","Swaption","30/360","SWISSEXCHANGE")

setMethod("show","Swaption",function(object){
			cat(optionType(object)," Swaption as of ",situationDate.character(object),"\n",sep="")
			cat("Name:     ",name(object),"\n",sep="")
			cat("Currency: ",currency(object),"\n",sep="")
			cat("Strike:   ",strike(object),"\n",sep="")
			cat("Vola:     ",impliedVolatility(object),"\n",sep="")
			cat("Nominal:  ",cashNumberToText(nominal(object)),"\n",sep="")
			cat("Effective Date: ",effectiveDate.character(object),"\n",sep="")
			cat("Maturity Date:  ",maturityDate.character(object),"\n",sep="")
		})

setMethod("presentValue",signature=c("Swaption","DiscountFactor"),function(object,arg1){
			SituationDate <- object@SituationDate
			EffectiveDate <- object@EffectiveDate
			MaturityDate <- object@MaturityDate
			FixPaymentFrequency <- object@FixPaymentFrequency
			DayCountConvention <- dayCountConvention(object)
			Exchange <- exchange(object)
			Currency <- currency(object)
			officialInterestDates <- monthlyDateSequence(EffectiveDate,MaturityDate,FixPaymentFrequency,Direction=-1,overlapping=FALSE,keepEndOfMonth=TRUE)
			interestPaymentDates <- getTradingDay(officialInterestDates,Exchange=object@Exchange,Direction=1)
			n <- length(interestPaymentDates)
			DFinUse <- arg1[interestPaymentDates,object@Currency]
			A <- sum(getData(DFinUse))
			FwdDF <- forwardDiscountFactor(EffectiveDate,arg1)
			Term <- round(yearFraction(EffectiveDate,MaturityDate))
			
			ParSwap <- estimateParSwapRate(Term, FixPaymentFrequency, Currency, "Swap Rate",EffectiveDate,DayCountConvention, Exchange, FwdDF)
			CFParSwap <- generateCashFlows(ParSwap)
			
			SK <- strike(object)
			StrikeSwap <- SwapRate(Term, SK, FixPaymentFrequency, Currency, "Swap Rate", EffectiveDate,DayCountConvention, Exchange)
			CFStrikeSwap <- generateCashFlows(StrikeSwap)
			CFDate <- getDate(CFStrikeSwap)
			CFDate <- CFDate[c(1,length(CFDate))]
			offsetCF <- CashFlow(Currency,"Swap Rate",CFDate,c(100,-100))
			
			CFParSwap <- CFParSwap + offsetCF
			CFStrikeSwap <- CFStrikeSwap + offsetCF
			
			
			S0 <- rate(ParSwap)
			T <- yearFraction(SituationDate,EffectiveDate)
			sigma <- impliedVolatility(object)/100
			
			# long receiver
			if(optionType(object)=="Receiver"){
				d1 <- (log(S0/SK)+sigma^2*T/2)/(sigma * sqrt(T))
				d2 <- d1 - sigma * sqrt(T)
				P <- getData((CFStrikeSwap * pnorm(-d2) - CFParSwap * pnorm(-d1))*arg1/100)
			}else{# long Payer
				d1 <- (log(S0/SK)+sigma^2*T/2)/(sigma * sqrt(T))
				d2 <- d1 - sigma * sqrt(T)
				P <- getData((CFParSwap * pnorm(d1) - CFStrikeSwap * pnorm(d2))*arg1/100)
			}
			
			P * nominal(object)			
		})

setMethod("presentValue",signature=c("Swaption","ZeroRateCurve"),function(object,arg1){
			presentValue(object,as.DiscountFactor(arg1))
		})
		
setMethod("dv01empirical",signature=c("Swaption","DiscountFactor"),function(object,arg1){
					presentValue(object,as.DiscountFactor(as.ZeroRateCurve(arg1)+0.01)) - presentValue(object,arg1)
				})

setMethod("dv01empirical",signature=c("Swaption","ZeroRateCurve"),function(object,arg1){
					dv01empirical(object,as.DiscountFactor(arg1))
				})		

setMethod("dv01",signature=c("Swaption","DiscountFactor"),function(object,arg1){
					delta <- 0.000000000001
					pv <- presentValue(object,arg1)
					pvplus <- presentValue(object,as.DiscountFactor(as.ZeroRateCurve(arg1)+delta))
					((pvplus - pv)/delta)/100
				})
		
setMethod("dv01",signature=c("Swaption","ZeroRateCurve"),function(object,arg1){
					dv01(object,as.DiscountFactor(arg1))
				})
		

setMethod("duration",signature=c("Swaption","DiscountFactor"),function(object,DF){
					-dv01(object,DF)/presentValue(object,DF)*10000
				})

setMethod("duration",signature=c("Swaption","ZeroRateCurve"),function(object,DF){
					DF <- as.DiscountFactor(DF)		
					-dv01(object,DF)/presentValue(object,DF)*10000
				})
		
setMethod("convexity",signature=c("Swaption","DiscountFactor"),function(object,DF){
					delta <- 0.000000000001
					pvplus <- presentValue(object,as.DiscountFactor(as.ZeroRateCurve(DF)+delta))
					pv <- presentValue(object,DF)
					pvminus <- presentValue(object,as.DiscountFactor(as.ZeroRateCurve(DF)-delta))
					d1 <- (pvplus - pv)/delta
					d2 <- (pv - pvminus)/delta
					(d1 - d2)/10
				})
		
setMethod("convexity",signature=c("Swaption","ZeroRateCurve"),function(object,DF){
					convexity(object,as.DiscountFactor(DF))
				})
# SituationDate <- DateYMD(2010,10,21)
# x <- object <- Swaption("Receiver",3,500000000,35,1,SituationDate,plusYear(SituationDate,10),plusYear(SituationDate,20),"CHF","Swaption","30/360","SWISSEXCHANGE")

#presentValue(x,DF)
#offset <- seq(-2,2,length.out=21)
#ZR <- as.ZeroRateCurve(DF)
#ZRall <- sapply(offset,function(x,y)y+x,ZR)
#DFall <- sapply(ZRall,as.DiscountFactor)

#px <- sapply(DFall,function(df,x)presentValue(x,df),x)
	
#plot(offset,px)




